import fs from 'fs';
import Long from 'long';
import uuid from 'uuid/v4';
import { keys } from 'ts-transformer-keys';
import grpc, { Metadata } from 'grpc';
import * as protoLoader from '@grpc/proto-loader';
import { inject, injectable, Container } from 'inversify';
import protobuf from 'protobufjs';
import grpcp from 'grpc-promise';
import { pick, RecursivePartial } from '@wellbye/joyce';
import Description from '../../gen/rpc/grpc-node';
import { Service as IRpcMbx } from '../../gen/rpc/mbx/MbxService/grpc-node';
import { PingMsg, Empty } from '../../gen/rpc/mbx';

import { bootEvent } from '../boot';
import { Config, container } from '../container';
import { Database } from '../db';
import { makeLabelLogger } from '../logger';
import { User } from '../entity/User';
import { Setting } from '../entity/Setting';
import { AsyncCounter } from 'src/container';

let { llog } = makeLabelLogger('grpc');

bootEvent.on('iocInit', async (container: Container, counter: AsyncCounter) => {
	let server = container.get<grpc.Server>('grpcServer');
	let proto = './assetsc/proto/main.proto';

	counter.add();
	let pakdef = await protoLoader.load(proto, {
		// enums: String
		includeDirs: ['./proto'],
	});
	let grpcObj = grpc.loadPackageDefinition(pakdef) as Description;
	server.addService(grpcObj.mbx.MbxService.service, new RpcMbx());

	counter.release();
});

////////////////////////////////////
@injectable()
class RpcMbx implements IRpcMbx {
	@inject(Database) db: Database;
	tokenMap = new Map<string, number>();
	////////////////////////

	Ping(
		call: grpc.ServerUnaryCall<PingMsg>,
		callback: grpc.sendUnaryData<Partial<PingMsg>>
	): void {
		llog('ping', call.request);
		callback(null, { no: call.request.no + 1 });
	}
}
